#pragma once
#include<QThreadPool>
#include<QRunnable>
#include<iostream>
#include<vector>
#include"ThreadPools.h"
using namespace std;

class MemUtil{
public:

    template<class T>
    static bool pairJudgeNull(const T& t1, const T& t2){
        return t1 == nullptr || t2 == nullptr;
    }

    template<class T>
    static void clearVecMem(vector<T>& vec){
        for(T ele : vec){
            if(ele != nullptr){
                delete ele;
                ele = nullptr;
            }
        }
        vec.clear();
    }

    template<class T>
    static void clearPtrMem(T& ptr){
        if(ptr != nullptr){
            delete ptr;
            ptr = nullptr;
        }
    }

    template<class T>
    static void clearPtrArrMem(T& ptr){
        if(ptr != nullptr){
            delete [] ptr;
            ptr = nullptr;
        }
    }

    template<class T>
    static void asyncClearPtrMem(const T& ptr);

    template<class T>
    static void asyncClearPtrArrMem(const T& ptr);

    template<class T>
    static void asyncClearVecMem(const vector<T>& vec);
};



template<class T>
class AsyncClear : public QRunnable{
private:
    T ele;
    bool isArr;

public:
    AsyncClear(const T& ele, const bool& isArr){
        this->ele = ele;
        this->isArr = isArr;
    }

    virtual void run(){
        isArr ? MemUtil::clearPtrArrMem(ele) : MemUtil::clearPtrMem(ele);
    }
};



template<class T>
class AsyncClearVec : public QRunnable{
private:
    vector<T> eleVec;

public:
    AsyncClearVec(const vector<T>& eleVec){
        this->eleVec = eleVec;
    }

    virtual void run(){
        MemUtil::clearVecMem(eleVec);
    }
};



template<class T>
void MemUtil::asyncClearPtrMem(const T& ptr){
    ThreadPools::commonAsyncClearThreadPool->start(new AsyncClear<T>(ptr, false));
}


template<class T>
void MemUtil::asyncClearPtrArrMem(const T& ptr){
    ThreadPools::commonAsyncClearThreadPool->start(new AsyncClear<T>(ptr, true));
}


template<class T>
void MemUtil::asyncClearVecMem(const vector<T>& vec){
    ThreadPools::commonAsyncClearThreadPool->start(new AsyncClearVec<T>(vec));
}

